/* 
 * File:   pipe_elements.h
 * Author: djs
 *
 * Created on March 28, 2011, 6:03 AM
 */

#ifndef PIPE_ELEMENTS_H
#define	PIPE_ELEMENTS_H
#include <map>
#include <queue>
#include "fdecode.h"
#include <deque>
#include <string>
#include <iostream>
extern int PC;
#define tJUMP 100;
#define tBRANCH 101;
using namespace std;
class registerFile;
class ROB;

class mBTB
{
public:
    int iaddr;
    int taddr;
    bool predict;
    mBTB(int a,int b);
    mBTB(){};

};

class BTB
{
public:
    map <int,mBTB> BTBl;
    queue <int> list;
    void fprint();
    void deleteatend();//done
    void insert(int,int);//done
    int getaddr(int);//done
    int member(int);//done
    int settaken(int);//done
    int setnottaken(int);//done
    int taken(int);
    int nottaken(int);
};
//------------------------------------------------------------------------------
class iQelement
{
public:
    bits instruction;
    int cycle;
    int addr;
    iQelement(bits, int ,int);
    iQelement(){cycle=0;};
    //int issuecycle;
};
class iQueue
{
public:
    deque <iQelement> IQ;
    iQueue(){};
    void push_back(bits,int,int);  //not done
    void fprint();
    void push_front(iQelement);
    iQelement next(int);
    void flush();
};
//-----------------------------------------------------------------------------
class CDBmember
{
public:

    int result;
    int value;
    string optype;
    int robid;
    int cycle;
    int loadcounter;//-1 for empty return
    int rsnumber;
    CDBmember(){result=0;value=0;robid=-1;cycle=-1;loadcounter=0;}
};
class CDB
{
public:
    deque <CDBmember> tCDB;
    CDBmember  getnext(int cycle);
    int add(int cycle,int result,int value,int robid,string op,int number);
    int add(int cycle,int result,int value,int robid,string op,int,int);
    int empty(int);
    void flush();
    void fprint();

};
//------------------------------------------------------------------------------
class rStation_member
{
public:
    int busy;
    int id;
    int vj,vk;
    int qj,qk;
    string op;
    int a;
    int robid;
    bits inst;
    int cycle;
    int executed;
    rStation_member(){busy=0;executed=0;}
    int opADDtype();
    int opADDItype();
    int opSLLtype();
    int opBNEtype();
    int opBGEZtype();
    int opBLEZtype();
    int opLWtype();
    int opSWtype();
    int execute(BTB &,ROB & ,int,iQueue &,CDB &);
};
class ROB;
class RS
{
public:
    rStation_member station[8];
    RS(){for(int i=0;i<8;i++)station[i].id=i;};
    int full();
    void setnotbusy(int);
    int issue(bits,int,int,int,ROB &,registerFile &);
    int execute(int,CDB &,BTB &,ROB &,iQueue &);
    void fprint();
    void update(CDBmember,int,int);
    void flush(int);
};
//-----------------------------------------------------------------------------
#define COMMIT 699
#define WRITERESULT 700
#define BUSY 701
class ROB_member
{
public:
    int issuecycle;
    int entry;
    int busy;
    bits instruction;
    int state;
    int destination;
    int value;
    int address;
    int updatecycle;
    ROB_member(){updatecycle=0;};
    void clear(){busy=0;state=0;};
};
class registerFile;
class ROB
{
public:
    ROB_member ROBlist[10];
    ROB();
    int freeid();
    void addat(int,iQelement,int,registerFile &);
    int commitable(int);
    int commit(registerFile &,int);
    int isready(int );
    int getvalue(int);
    void fprint();
    void update(CDBmember,int,CDB & );
    int head(int );
    void flush(int);
};
//-----------------------------------------------------------------------------
class registerMember
{
public:
    
    int value;
    int ROBid;
    bool busy;
    registerMember(){value=0;ROBid=-1;busy=0;};
};
class registerFile
{
public:
    registerMember list[32];
    int getvalue(int a){return list[a].value;}
    void write(int a,int v){list[a].value=v;list[a].busy=0;list[a].ROBid=-1;};
    void setbusy(int a){list[a].busy=1;}
    void setfree(int a){list[a].busy=0;}
    bool isbusy(int a){return list[a].busy ;}
    int getROB(int a){return list[a].ROBid;}
    bool setrobid(int a,int robid){list[a].ROBid=robid;}
};
//-----------------------------------------------------------------------------
class pipeline
{
public:
    registerFile rRF;
    ROB rROB;
    RS rRS;
    iQueue rIQ;
    BTB rBTB;
    CDB rCDB;
    
    pipeline(){};
    int fetch();
    int issue();
    int execute();
    int writeresult();
    int commit();

};


#endif	/* PIPE_ELEMENTS_H */

